<?php
/*
 * ebiz front
 *
 * Customer Service
 *
 * @author allen
 *
 */
require_once '../app/core/services/BaseService.php';
require_once '../app/models/OrderDao.php';
require_once '../app/util/Pager.php';
require_once '../conf/config.php';
require_once '../app/models/OrderItemDao.php';
require_once '../app/models/OrderPackageDao.php';
require_once '../app/models/OrderPackageItemDao.php';
require_once '../app/models/WishlistDao.php';
require_once '../app/component/Number.php';
require_once '../app/models/ShoppingCartDao.php';
require_once '../app/models/ProductItemDao.php';
require_once '../app/models/CategoryProductDao.php';
require_once '../app/models/AreaDictDao.php';
require_once '../app/models/DeliveryInfoDao.php';
require_once '../app/models/ProfitRatioDao.php';
require_once '../app/models/AccountAgentTotalDao.php';
require_once '../app/models/AccountAgentTradeLogsDao.php';
require_once '../app/services/SystemLogService.php';
require_once '../app/services/AAService.php';
require_once '../app/models/MetadataDao.php';
require_once '../app/models/MetadataOptionDao.php';
require_once '../app/models/UserDao.php';
require_once '../app/services/UserPointService.php';

class OrderService extends BaseService {
    private $orderDao;
    private $orderItemDao;
    private $orderPackageDao;
    private $orderPackageItemDao;
    private $wishlistDao;
    private $shoppingCartDao;
    private $productItemDao;
    private $areaDictDao;
    private $deliveryInfoDao;
    private $profitRatioDao;
    private $categoryProductDao;
    private $metadataDao;
    private $metadataOptionDao;
    private $agentTotalDao;
    private $accountAgentTradeLogDao;
    private $paymentLogDao;
    private $userDao;

    public function __construct(){
         parent::__construct();
         $this->orderDao = new OrderDao($this->dbUtil);
         $this->orderItemDao = new OrderItemDao($this->dbUtil);
         $this->orderPackageDao = new OrderPackageDao($this->dbUtil);
         $this->orderPackageItemDao = new OrderPackageItemDao($this->dbUtil);
         $this->shoppingCartDao = new ShoppingCartDao($this->dbUtil);
         $this->productItemDao = new ProductItemDao($this->dbUtil);
         $this->wishlistDao = new WishlistDao($this->dbUtil);
         $this->areaDictDao = new AreaDictDao($this->dbUtil);
         $this->deliveryInfoDao = new DeliveryInfoDao($this->dbUtil);
         $this->profitRatioDao = new ProfitRatioDao($this->dbUtil);
         $this->categoryProductDao = new CategoryProductDao($this->dbUtil);
         $this->agentTotalDao = new AccountAgentTotalDao($this->dbUtil);
         $this->accountAgentTradeLogDao = new AccountAgentTradeLogsDao($this->dbUtil);
         $this->metadataDao = new MetadataDao($this->dbUtil);
         $this->metadataOptionDao = new MetadataOptionDao($this->dbUtil);
         $this->userDao = new UserDao($this->dbUtil);
    }

    /**
     * use the address id to get the address title
     */
    public function getAddressTitle($topAddress){
        $selectAddress = array();
    	foreach ($topAddress as $address) {
            $province = $this->areaDictDao->getAreaById($address['address_1']);
            $city = $this->areaDictDao->getAreaById($address['address_2']);
            $district = $this->areaDictDao->getAreaById($address['address_3']);
            $selectAddress[] = array("id" => $address['id'],
                                     "user_id" => $address['user_id'],
                                     "name" => $address['name'],
                                     "phone_number_1" => $address['phone_number_1'],
                                     "phone_number_2" => $address['phone_number_2'],
                                     "address_1" => $province[0]['title'],
                                     "address_2" => $city[0]['title'],
                                     "address_3" => $district[0]['title'],
                                     "addressid_1" => $address['address_1'],
                                     "addressid_2" => $address['address_2'],
                                     "addressid_3" => $address['address_3'],
                                     "detail_address" => $address['detail_address'],
                                     "email" => $address['email'],
                                     "agent_address" => $address['agent_address'],
                                     "count" => $address['count'],
                                     "modified" => $address['modified'],
                                     "created" => $address['created']);
        }
        return $selectAddress;
    }

    /**
     * get the shipping type : weight or fixed
     */
    public function getShipRule($shoppingCartInfoToCheckout){
        //1==fixed,2==weight,3==freeshipping
        $fixedType = 0;
        $weightType = 0;
        $freeType = 0;
        foreach ($shoppingCartInfoToCheckout as $item) {
            if($item["ship_rule"] == 1){
                $fixedType++;
            }elseif($item["ship_rule"] == 2){
                $weightType++;
            }elseif($item["ship_rule"] == 3){
                $freeType++;
            }
        }
        if($weightType == 0 && $fixedType == 0 && $freeType > 0){//the shipping rule is free shipping
            $shipRule = 3;
        }elseif($weightType == 0 && ($fixedType > 0 || $freeType > 0)){//by fixed
            $shipRule = 1;
        }else{//by weight
            $shipRule = 2;
        }
        return $shipRule;
    }

    /**
     * if current ship fee is order by weight
     */
    public function countShipFeeByWeight($provinceId, $freeShippingMethod){
        $result = array();
        $itemIds = HttpUtil::getPostString("itemIds");
        $quantitys = HttpUtil::getPostString("quantitys");
        $weights = HttpUtil::getPostString("weights");
        $shipRules = HttpUtil::getPostString("shipRules");
        $itemIdArray = explode(",", $itemIds);
        $quantityTempArray = explode(",", $quantitys);
        $weightTempArray = explode(",", $weights);
        $shipRuleTempArray = explode(",", $shipRules);
        $allWeight = 0;
        for($i = 0; $i < count($itemIdArray); $i++){
            if($shipRuleTempArray[$i] != 3){
                $allWeight += $quantityTempArray[$i] * $weightTempArray[$i];
            }
        }
        //if is free shipping
        if($allWeight == 0){
            $result["normal"] = 0;
            $result["SF"] = 0;
            $result["EMS"] = 0;
        }else{
            //normal delivery
            if(array_key_exists($provinceId, Order::getNormalPaymentProvinceFeeList())){
                $initFee = Order::$normalWeightFee;
                if($allWeight <= 1){
                    $normalShipFee = $initFee;
                }else{
                    $perFee = Order::getNormalPaymentProvinceFee($provinceId);
                    $countWeight = ceil($allWeight - 1);
                    $normalShipFee = $countWeight * $perFee + $initFee;
                }
            }else{
                $initFee = Order::$normalWeightFee;
                if($allWeight <= 1){
                    $normalShipFee = $initFee;
                }else{
                    $perFee = Order::getNormalPaymentProvinceFee(0);
                    $countWeight = ceil($allWeight - 1);
                    $normalShipFee = $countWeight * $perFee + $initFee;
                }
            }
            //SF delivery
            if($provinceId == 3306 || $provinceId == 2916){
                $SFShipFee = 0;
            }else{
                if(array_key_exists($provinceId, Order::getSFPaymentProvinceFeeList())){
                    $initFee = Order::$SFWeightFee;
                    if($allWeight <= 1){
                        $SFShipFee = $initFee;
                    }else{
                        $perFee = Order::getSFPaymentProvinceFee($provinceId);
                        $countWeight = ceil($allWeight - 1);
                        $SFShipFee = $countWeight * $perFee + $initFee;
                    }
                }else{
                    $initFee = Order::$SFWeightFee;
                    if($allWeight <= 1){
                        $SFShipFee = $initFee;
                    }else{
                        $perFee = Order::getSFPaymentProvinceFee(0);
                        $countWeight = ceil($allWeight - 1);
                        $SFShipFee = $countWeight * $perFee + $initFee;
                    }
                }
            }
            //EMS delivery
            if(array_key_exists($provinceId, Order::getEMSPaymentProvinceFeeList())){
                $initFee = Order::$EMSWeightFee;
                if($allWeight <= 1){
                    $EMSShipFee = $initFee;
                }else{
                    $perFee = Order::getEMSPaymentProvinceFee($provinceId);
                    $countWeight = ceil($allWeight - 1);
                    $EMSShipFee = $countWeight * $perFee + $initFee;
                }
            }else{
                $initFee = Order::$EMSWeightFee;
                if($allWeight <= 1){
                    $EMSShipFee = $initFee;
                }else{
                    $perFee = Order::getEMSPaymentProvinceFee(0);
                    $countWeight = ceil($allWeight - 1);
                    $EMSShipFee = $countWeight * $perFee + $initFee;
                }
            }
            $result["normal"] = $normalShipFee;
            $result["SF"] = $SFShipFee;
            $result["EMS"] = $EMSShipFee;
            if( $freeShippingMethod == 1 ){
                $result["normal"] = 0;
            }elseif( $freeShippingMethod == 5 ){
                $result["SF"] = 0;
            }elseif( $freeShippingMethod == 2 ){
                $result["EMS"] = 0;
            }
        }
        return $result;

    }

    /**
     * the checkout page entrance service
     */
    public function placeOrder(){
        $addressId = HttpUtil::getPostString("address");
        $deliveryRadio = HttpUtil::getPostString("deliveryRadio");
        $deliveryDate = HttpUtil::getPostString("deliveryDate");
        $radioPay = HttpUtil::getPostString("radioPay");
        $orderNum = Number::getOrderNumber();
        $userId = AAService::getCustomer();
        if($deliveryRadio == 3){//campuses
            $status = 11;
            $shippingTime = $deliveryDate;
        }else{
            $status = 1;
            $shippingTime = 0;
        }
        $shippingFee = HttpUtil::getPostString("shippingCharges");
        $discountFee = HttpUtil::getPostString("discount");
//        $taxFeeTotal = number_format(HttpUtil::getPostString("estimatedTax"), 2);
        $taxFeeTotal = HttpUtil::getPostString("estimatedTax");
        $merchandiseTotal = HttpUtil::getPostString("merchandiseTotal");
        $total = HttpUtil::getPostString("allTotal");
        $shipProfitTotal = 0;
        $orderProfitTotal = 0;
        $shippingExpect = $deliveryRadio;
        $paymentMethod = $radioPay;
        $invoice = HttpUtil::getPostString("invoiceTitle");
        $agentCampusId = HttpUtil::getPostString("campusesId") == "" ? 0 : HttpUtil::getPostString("campusesId");
        $agentId = HttpUtil::getPostString("userId");
        $addressInfo = self::getDeliveryAddress($addressId);
        $deliveryName = $addressInfo[0]['name'];
        $deliveryPhone1 = $addressInfo[0]['phone_number_1'];
        $deliveryPhone2 = $addressInfo[0]['phone_number_2'];
        $deliveryAddress1 = $addressInfo[0]['address_1'];
        $deliveryAddress2 = $addressInfo[0]['address_2'];
        $deliveryAddress3 = $addressInfo[0]['address_3'];
        $deliveryDetailAddress = $addressInfo[0]['detail_address'];
        $deliveryEmail = $addressInfo[0]['email'];
        $remark = HttpUtil::getPostString("textarea");
        $isReturn = 0;
        $createdId = $_SESSION["username"];
        $modifiedId = $_SESSION["username"];
        //get the order item info
        $itemId = HttpUtil::getPostValue("itemId");
        $itemStatus = 1;
        $quantity = HttpUtil::getPostValue("quantity");
        $salePrice = HttpUtil::getPostValue("salePrice");
        $dealPrice = HttpUtil::getPostValue("dealPrice");
        $discountPrice = HttpUtil::getPostValue("hiddenDiscountPrice");
        $taxFee = HttpUtil::getPostValue("hiddenTaxFee");
        $chequeRule = HttpUtil::getPostValue("chequeRule");

        //current shipping method is campus ship then count the profit price , 1 is ShipPrice , 2 is OrderPrice
        $userCertf = $_SESSION["certf"];
        $shipProfitTotal = 0;//save in order table , this is ship profit total price
        $orderProfitTotal = 0;//save in order table , this is order profit total price
        $profitAllShipPrice = 0;//ship profit price array
        $profitAllOrderPrice = 0;//order profit price array
        if($deliveryRadio == 3){//if current is campus delivery
            //count ship profit
            $shipCertf = HttpUtil::getPostString("userId");//get agent id
            if(!empty($shipCertf)){//else set profitAllShipPrice is zero
                $profitAllShipPrice = self::countOrderProfit($itemId, $quantity, $dealPrice, 1);
            }
            //count order profit
            $profitAllOrderPrice = self::countOrderProfit($itemId, $quantity, $dealPrice, 2);
        }
        
        if($userCertf == 1){//user if his certf is normal user then order profit is zero , his order profit put in ship profit
            if($profitAllOrderPrice != 0){
                if($profitAllShipPrice != 0){//current have agent id
                   for($i = 0; $i < count($profitAllOrderPrice); $i++){//set the ship profit price to order profit
                        $profitAllShipPrice[$i] += $profitAllOrderPrice[$i];
                    }
                }else{//if is 0(current not have agent id) then set value is $profitAllOrderPrice
                    $profitAllShipPrice = $profitAllOrderPrice;
                }
                $profitAllOrderPrice = 0;
            }
        }
//        if($profitAllShipPrice != 0){
        if( !empty($profitAllShipPrice) ){
            foreach ($profitAllShipPrice as $price) {
                $shipProfitTotal += $price;
            }
        }
//        if($profitAllOrderPrice != 0){
        if( !empty($profitAllOrderPrice) ){
            foreach ($profitAllOrderPrice as $price) {
                $orderProfitTotal += $price;
            }
        }

        //save order info
        $orderInfo = array(
                           $orderNum,
                           $userId,
                           $status,
                           $shippingFee,
                           $discountFee,
                           $taxFeeTotal,
                           $merchandiseTotal,
                           $total,
                           $shipProfitTotal,
                           $orderProfitTotal,
                           $shippingTime,
                           $shippingExpect,
                           $paymentMethod,
                           $invoice,
                           $agentCampusId,
                           $agentId,
                           $deliveryName,
                           $deliveryPhone1,
                           $deliveryPhone2,
                           $deliveryAddress1,
                           $deliveryAddress2,
                           $deliveryAddress3,
                           $deliveryDetailAddress,
                           $deliveryEmail,
                           $remark,
                           $isReturn,
                           $createdId,
                           $modifiedId
                           );
        $orderId = self::saveOrderInfo($orderInfo);
        //add used coupon log in promotion log table
        $couponCodes = HttpUtil::getPostString("hiddenUsedPromotion");
        $promotionImplService = new PromotionImplService();
        $promotionImplService->logPromotion($orderId, $couponCodes, $userId);
        //update the exchange promotion info 
        $usedPromotionCode = HttpUtil::getPostString("hiddenUsedPromotionCode");
        $promotionImplService->changeGiftLog($usedPromotionCode, $userId);
        
        
        //save order item info to order table

        self::saveOrderItems($orderId, $itemId, $itemStatus, $quantity, $salePrice, $dealPrice, $discountPrice, $taxFee, $chequeRule, $createdId, $modifiedId, $profitAllShipPrice, $profitAllOrderPrice);
        //after user bought goods , clear shopping cart table info by customer id
        $this->shoppingCartDao->deleteShoppingCartByCustomerId($userId);
        //subtract the user buy quantity from product_items table
        for($i = 0;$i < count($itemId); $i++){
            $this->productItemDao->updateInventoryByItemId($itemId[$i], $quantity[$i]);
        }
        return $orderId;
    }

    /**
     * count the order profit or ship profit
     * return the result of profit price order by item id
     */
    private function countOrderProfit($itemIdArray, $quantityArray, $dealPriceArray, $ratioType){
        $result = array();
        for($i = 0; $i < count($itemIdArray); $i++){
            $itemId = $itemIdArray[$i];
            $quantity = $quantityArray[$i];
            $dealPrice = $dealPriceArray[$i];
            $totalPrice = $dealPrice * $quantity;
            $profit = $this->profitRatioDao->getProfitByItemIdAndType($itemId, $ratioType);
            if(empty($profit)){//如果找不到收益
            	if($ratioType == 1){//默认配送收益为千分之20
            		$profitRatio = 20;
            	}else{//默认下单收益为0
            		$profitRatio = 0;
            	}
            }else{
            	$profitRatio = $profit[0]["ratio"];
            }
//            $profitRatio = $profit[0]["ratio"];
            $result[] =  $totalPrice * $profitRatio * 0.001;
        }
        return $result;
    }

    /**
     * get the delivery address by id
     */
    public function getDeliveryAddress($addressId){
        return $this->deliveryInfoDao->getAddressInfoById($addressId);
    }

    /**
     * save the order info to order table and return current order info
     */
    public function saveOrderInfo($orderInfo){
        $orderId = $this->orderDao->saveOrder($orderInfo);
        return $orderId;
    }

    /**
     * check order,now first set 2 is PROCESSING
     */
    private function checkOrder($orderId){
        $orderStatus = 2;
        $this->orderDao->updateOrder($orderId, $orderStatus);
        return true;
    }

    /**
     * save order item info
     */
    public function saveOrderItems($orderId, $itemId, $itemStatus, $quantity, $salePrice, $dealPrice, $discountPrice, $taxFee, $chequeRule, $createdId, $modifiedId, $profitAllShipPrice, $profitAllOrderPrice){
        for ($i = 0; $i < count($itemId); $i++){
            $chequeStatus = HttpUtil::getPostString("invoiceCheck_".$itemId[$i]);
            if($profitAllShipPrice == 0 && $profitAllOrderPrice != 0){
                $orderItemInfo = array(
                                   $orderId,
                                   $itemId[$i],
                                   $itemStatus,
                                   $quantity[$i],
                                   $salePrice[$i],
                                   $dealPrice[$i],
                                   $discountPrice[$i],
                                   $taxFee[$i],
                                   $chequeRule[$i],
                                   $profitAllOrderPrice[$i],
                                   $profitAllShipPrice,
                                   $chequeStatus,
                                   $modifiedId,
                                   $createdId
                                   );
            }elseif($profitAllShipPrice != 0 && $profitAllOrderPrice == 0){
                $orderItemInfo = array(
                                   $orderId,
                                   $itemId[$i],
                                   $itemStatus,
                                   $quantity[$i],
                                   $salePrice[$i],
                                   $dealPrice[$i],
                                   $discountPrice[$i],
                                   $taxFee[$i],
                                   $chequeRule[$i],
                                   $profitAllOrderPrice,
                                   $profitAllShipPrice[$i],
                                   $chequeStatus,
                                   $modifiedId,
                                   $createdId
                                   );
            }elseif($profitAllShipPrice == 0 && $profitAllOrderPrice == 0){
                $orderItemInfo = array(
                                       $orderId,
                                       $itemId[$i],
                                       $itemStatus,
                                       $quantity[$i],
                                       $salePrice[$i],
                                       $dealPrice[$i],
                                       $discountPrice[$i],
                                       $taxFee[$i],
                                       $chequeRule[$i],
                                       $profitAllOrderPrice,
                                       $profitAllShipPrice,
                                       $chequeStatus,
                                       $modifiedId,
                                       $createdId
                                       );
            }else{
                $orderItemInfo = array(
                                       $orderId,
                                       $itemId[$i],
                                       $itemStatus,
                                       $quantity[$i],
                                       $salePrice[$i],
                                       $dealPrice[$i],
                                       $discountPrice[$i],
                                       $taxFee[$i],
                                       $chequeRule[$i],
                                       $profitAllOrderPrice[$i],
                                       $profitAllShipPrice[$i],
                                       $chequeStatus,
                                       $modifiedId,
                                       $createdId
                                       );
            }
            $this->orderItemDao->saveOrderItemInfo($orderItemInfo);
        }
    }

    /**
     * success order service
     *
     * get order info and address info by orderId
     */
    public function getOrderInfoById($orderId){
        $result = $this->orderDao->getOrderAndAddressInfoByOrderId($orderId);
        return $result;
    }

    /**
     * get the order item info show in success page
     */
    public function getOrderItemInfoByOrderId($orderId){
        $orderItems = $this->orderItemDao->getItemInfoByOrderId($orderId);
        return $orderItems;
    }

    /**
     * get the order item info show in success page
     * @author by M.Wang
     */
    public function getOrderItemInfoByOrderIdByWang($orderId){
        $orderItems = $this->orderItemDao->getItemInfoByOrderIdByWang($orderId);
        return $orderItems;
    }

    /**
     * judge the user bought quantity if less than inventity of DB,if more than DB then return false,user can not to buy
     */
    public function isCanBuyGood($itemIds, $quantityArray){
        $itemInfoArray = $this->productItemDao->getByIds($itemIds); //get all item info
        for($i = 0; $i < count($itemInfoArray); $i++) {
            if($itemInfoArray[$i]['inventory'] <= 0){
                return false;
            }else if($itemInfoArray[$i]['inventory'] < $quantityArray[$i]){
                return false;
            }
        }
        return true;
    }

    /**
     * get the qty and inventory info in checkout page
     */
    public function getItemQtyInfoForCheckOut($itemIds, $qtyArray, $customerId){
        $result = array();
        $itemInfoArray = $this->shoppingCartDao->getInventoryInfoByItemIdAndCid($itemIds, $customerId); //get all item info
        for($i = 0; $i < count($itemInfoArray); $i++){
            if($itemInfoArray[$i]['piIsDelete'] != 0 || $itemInfoArray[$i]['pIsDelete'] != 0){ //this item is already deleted
                $result[] = array("itemId" => $itemInfoArray[$i]['pItemId'],
//                                "scId" => $itemInfoArray[$i]['scId'],
                                  "title" => $itemInfoArray[$i]['title'],
                                  "attr1" => $itemInfoArray[$i]['attribute_1'],
                                  "value1" => $itemInfoArray[$i]['value_1'],
                                  "attr2" => $itemInfoArray[$i]['attribute_2'],
                                  "value2" => $itemInfoArray[$i]['value_2'],
                                  "error" => "delete"
                                  );
            }else{
                if($itemInfoArray[$i]['inventory'] == 0){
                    $result[] = array("itemId" => $itemInfoArray[$i]['pItemId'],
//                                      "scId" => $itemInfoArray[$i]['scId'],
                                      "title" => $itemInfoArray[$i]['title'],
                                      "attr1" => $itemInfoArray[$i]['attribute_1'],
                                      "value1" => $itemInfoArray[$i]['value_1'],
                                      "attr2" => $itemInfoArray[$i]['attribute_2'],
                                      "value2" => $itemInfoArray[$i]['value_2'],
                                      "error" => "none"
                                      );
                }else if($itemInfoArray[$i]['inventory'] < $qtyArray[$i]){
                    $result[] = array("itemId" => $itemInfoArray[$i]['pItemId'],
//                                      "scId" => $itemInfoArray[$i]['scId'],
                                      "title" => $itemInfoArray[$i]['title'],
                                      "attr1" => $itemInfoArray[$i]['attribute_1'],
                                      "value1" => $itemInfoArray[$i]['value_1'],
                                      "attr2" => $itemInfoArray[$i]['attribute_2'],
                                      "value2" => $itemInfoArray[$i]['value_2'],
                                      "error" => $itemInfoArray[$i]['inventory']
                                      );
                }else if($itemInfoArray[0]['sale_price'] <= 0){
                    $result[] = array("itemId" => $itemInfoArray[$i]['pItemId'],
//                                      "scId" => $itemInfoArray[$i]['scId'],
                                      "title" => $itemInfoArray[$i]['title'],
                                      "attr1" => $itemInfoArray[$i]['attribute_1'],
                                      "value1" => $itemInfoArray[$i]['value_1'],
                                      "attr2" => $itemInfoArray[$i]['attribute_2'],
                                      "value2" => $itemInfoArray[$i]['value_2'],
                                      "error" => "priceerror"
                                      );
                }
            }
        }
        return $result;
    }
    
    /**
     * get the sale price info in checkout page
     */
    public function getItemSalePriceForCheckout($salePriceResultArray){//key is itemid , value is saleprice
    	$result = array();
        foreach ($salePriceResultArray as $itemId => $salePrice) {
        	$itemInfo = $this->productItemDao->getItemInfoByItemIds($itemId);
        	$DBSalePrice = $itemInfo[0]["sale_price"];
        	if( $DBSalePrice != $salePrice ){
        		$result[] = array(
        		                  "title" => $itemInfo[0]["title"],
        		                  "db_sale_price" => $itemInfo[0]["sale_price"],
        		                  "sale_price" => $salePrice
        		);
        	}
        }
        return $result;
    }

    /**
     * generate the shipping method from config table
     */
    public static function getShippingExpectListFromDB(){
        $result = array();
        $config = $GLOBALS["config"];
        $shippingMethodSetting = $config['shipping_method_setting'];
        if(empty($shippingMethodSetting)){
            return $result;
        }
        $shippingMethodSettingArray = explode(",", $shippingMethodSetting);
        foreach ($config as $key => $value) {
            if(substr($key, 0, 15) == "shipping_method" && strlen($key) < 18){//delete the shipping_method_setting key
                foreach ($shippingMethodSettingArray as $shippingMethodKey) {
                    if(substr($key, 16, 17) == $shippingMethodKey){
                        $result[$shippingMethodKey] = $value;
                    }
                }
            }
        }
        return $result;
    }

    /**
     * generate the payment method from config table
     */
    public static function getPaymentMethodFromDB(){
        $result = array();
        $config = $GLOBALS["config"];
        $paymentMethodSettings = $config['payment_method_settings'];
        if(empty($paymentMethodSettings)){
            return $result;
        }
        $paymentMethodSettingsArray = explode(",", $paymentMethodSettings);
        foreach ($paymentMethodSettingsArray as $key) {
            $result[$key] = Order::getPaymentMethod($key);
        }
        return $result;
    }

    /**
     * count the tax
     */
    public function countTax($cityName, $itemIds, $totals, $stateName){
        $itemIdArray = explode(",", $itemIds);
        $totalArray = explode(",", $totals);
        foreach ($itemIdArray as $key => $item) {
            $itemPrice[$item] = $totalArray[$key];
        }
        $cityTaxInfo = $this->cityTaxDao->getTaxByStateAndCity($cityName, $stateName);
        if(!empty($cityTaxInfo)){
            $cityTax = $cityTaxInfo[0]['tax_rate'];
            if($cityTax + 0 <= 0){//this city do not use tax
                return 0;
            }else{//this city can use tax
                $salePrice = 0;
                //$productItemInfo = $this->productItemDao->getByIds($itemIds);
                foreach ($itemPrice as $key => $value) {
                    $productItemInfo = $this->productItemDao->getById($key);
                    if($productItemInfo[0]['taxable'] == 1){
                        //$salePrice += $productItemInfo[0]['sale_price'];
                        $salePrice += $value;
                    }
                }
                $tax = $salePrice * $cityTax * 0.01;
                return $tax;
            }
        }
    }

    /**
     * generate the item attribute by item id
     * query metadata and metadata_option table to replay the attribute and value of item table
     */
    public function getItemAttribute($itemId){
        $result = array();
        $itemInfo = $this->productItemDao->getById($itemId);
        $attr1 = $itemInfo[0]['attribute_1'] == null ? "" : $itemInfo[0]['attribute_1'];
        $attr2 = $itemInfo[0]['attribute_2'] == null ? "" : $itemInfo[0]['attribute_2'];
        $attr3 = $itemInfo[0]['attribute_3'] == null ? "" : $itemInfo[0]['attribute_3'];
        $attr4 = $itemInfo[0]['attribute_4'] == null ? "" : $itemInfo[0]['attribute_4'];
        $attr5 = $itemInfo[0]['attribute_5'] == null ? "" : $itemInfo[0]['attribute_5'];
        $value1 = $itemInfo[0]['value_1'] == null ? "" : $itemInfo[0]['value_1'];
        $value2 = $itemInfo[0]['value_2'] == null ? "" : $itemInfo[0]['value_2'];
        $value3 = $itemInfo[0]['value_3'] == null ? "" : $itemInfo[0]['value_3'];
        $value4 = $itemInfo[0]['value_4'] == null ? "" : $itemInfo[0]['value_4'];
        $value5 = $itemInfo[0]['value_5'] == null ? "" : $itemInfo[0]['value_5'];
        $metadata1 = $itemInfo[0]["metadata_1"];
        $metadata2 = $itemInfo[0]["metadata_2"];
        $metadata3 = $itemInfo[0]["metadata_3"];
        $metadata4 = $itemInfo[0]["metadata_4"];
        $metadata5 = $itemInfo[0]["metadata_5"];
        $key1 = $itemInfo[0]["key_1"];
        $key2 = $itemInfo[0]["key_2"];
        $key3 = $itemInfo[0]["key_3"];
        $key4 = $itemInfo[0]["key_4"];
        $key5 = $itemInfo[0]["key_5"];
        //attribute1
        if(!empty($metadata1)){
            $isOptionType1 = self::isOptionType($metadata1);
            $attribute1Title = "";
            $attribute1ColorPath = "";
            if(self::isColorAttribute($metadata1)){
                $result1 = self::getAttributeValueTitleAndPath($metadata1, $key1);
                $attr1 = $result1["metadata_title"];
                $attribute1ColorPath = $result1["path"];
                if($isOptionType1){//true is 3 or 6
                    $value1 = $key1;
                    $attribute1Title = $result1["metadata_options_title"];
                }else{//false is use item table value
                    $attribute1Title = $value1;
                }
            }else{
                $result1 = self::getAttributeValueAndTitle($metadata1, $key1);
                $attr1 = $result1["metadata_title"];
                if($isOptionType1){//true is 3 or 6
                    $value1 = $key1;
                    $attribute1Title = $result1["metadata_options_title"];
                }else{
                    $attribute1Title = $value1;
                }
            }
            $result[] = array("attr"=>$attr1, "value"=>$value1, "attr_title"=>$attribute1Title, "attr_color_path"=>$attribute1ColorPath);
        }

        //attribute2
        if(!empty($metadata2)){
            $result2 = self::getAttributeValueAndTitle($metadata2, $key2);
            $attr2 = $result2["metadata_title"];
            if(self::isOptionType($metadata2)){//true is 3 or 6
                $value2 = $key2;
                $attribute2Title = $result2["metadata_options_title"];
            }else{
                $attribute2Title = $value2;
            }
            $result[] = array("attr"=>$attr2, "value"=>$value2, "attr_title"=>$attribute2Title);
        }
        //attribute3
        if(!empty($metadata3)){
            $result3 = self::getAttributeValueAndTitle($metadata3, $key3);
            $attr3 = $result3["metadata_title"];
            if(self::isOptionType($metadata3)){//true is 3 or 6
                $value3 = $key3;
                $attribute3Title = $result3["metadata_options_title"];
            }else{
                $attribute3Title = $value3;
            }
            $result[] = array("attr"=>$attr3, "value"=>$value3, "attr_title"=>$attribute3Title);
        }
        //attribute4
        if(!empty($metadata4)){
            $result4 = self::getAttributeValueAndTitle($metadata4, $key4);
            $attr4 = $result4["metadata_title"];
            if(self::isOptionType($metadata4)){//true is 3 or 6
                $value4 = $key4;
                $attribute4Title = $result4["metadata_options_title"];
            }else{
                $attribute4Title = $value4;
            }
            $result[] = array("attr"=>$attr4, "value"=>$value4, "attr_title"=>$attribute4Title);
        }
        //attribute5
        if(!empty($metadata5)){
            $result5 = self::getAttributeValueAndTitle($metadata5, $key5);
            $attr5 = $result5["metadata_title"];
            if(self::isOptionType($metadata5)){//true is 3 or 6
                $value5 = $key5;
                $attribute5Title = $result5["metadata_options_title"];
            }else{
                $attribute5Title = $value5;
            }
            $result[] = array("attr"=>$attr5, "value"=>$value5, "attr_title"=>$attribute5Title);
        }
        return $result;
    }


    /**
     * judge current all attribute type if is 3 or 6
     * return boolean
     */
    public function isOptionType($metadataId){
        $metadata = $this->metadataDao->getMetadataById($metadataId);
        $metadataType = $metadata[0]["input_type"];
        if($metadataType == 3 || $metadataType == 6){//3 or 6 is dropDown or option
            return true;
        }else{
            return false;
        }
    }

    /**
     * judge the attribute_1 if is color
     * return boolean
     */
    public function isColorAttribute($metadataId){
        $metadata = $this->metadataDao->getMetadataById($metadataId);
        $metadataTitle = $metadata[0]["title"];
        $findTitle = "颜色";
        $pos = strpos($metadataTitle, $findTitle);
        if ($pos === false) {
            return false;
        }else{
            return true;
        }
    }

    /**
     * get the attribute and value and title
     * use in attribute 1
     * $metadataId is metadata_1 , $metadataOptionId is key_1
     */
    public function getAttributeValueTitleAndPath($metadataId, $metadataOptionId){//$metadataKey is not 0 or null
        $result = array();
        $metadata = $this->metadataDao->getMetadataById($metadataId);
        $metadataTitle = $metadata[0]["title"];//show the color title
        $metadataOptions = $this->metadataOptionDao->getMetadataOptionsById($metadataOptionId);
        $metadataOptionsTitle = $metadataOptions[0]["title"];
        $metadataOptionsValue = $metadataOptions[0]["value"];
        $color = $GLOBALS["color"];
        $colorPath = $color[$metadataOptionsValue];
        $result["metadata_title"] = $metadataTitle;
        $result["metadata_options_title"] = $metadataOptionsTitle;
        $result["path"] = $colorPath;
        return $result;
    }

    /**
     * get the attribute and value and title
     * use in attribute 2-5
     */
    public function getAttributeValueAndTitle($metadataId, $metadataOptionId){//$metadataKey is not 0 or null
        $result = array();
        $metadata = $this->metadataDao->getMetadataById($metadataId);
        $metadataTitle = $metadata[0]["title"];
        $metadataOptions = $this->metadataOptionDao->getMetadataOptionsById($metadataOptionId);
        $metadataOptionsTitle = $metadataOptions[0]["title"];
        $result["metadata_title"] = $metadataTitle;
        $result["metadata_options_title"] = $metadataOptionsTitle;
        return $result;
    }

    /*
     * product page show this item number of already sale out
     */
    public function getSuccessOrderItemNumByItemId($itemId){
        $result = $this->orderItemDao->getSuccessOrderItemNumByItemId($itemId);
        $number = $result[0]["count(*)"];
        return $number;
    }

///////////////////////////////////////////////////////////////////

    /**
     * Get orders base info by agent id
     *
     * @author by M.Wang
     * @param int $int_id
     * @param int $int_page
     * @param int $int_limit
     * @param string $str_otherCondition
     * @return array
     */
    public function getOrdersBySuperAgentId( $int_id, $int_start, $int_limit, $str_otherCondition = '' ){
       return $this->orderDao->getOrdersByAgentId( $int_id, $int_start, $int_limit, $str_otherCondition );
    }

    public function getOrdersCountRowsBySuperAgentId($int_id, $str_otherCondition = null){
        $arr_results = $this->orderDao->getOrdersByAgentId($int_id, null, null, $str_otherCondition, true);
        if( $arr_results ){
    	   $arr_results['Count'] = $this->dbUtil->getLastFoundRows();
    	 
    	}
        return $arr_results['Count'][0]['ROWS'];
       
    }

    /**
     * Get orders base info by user id
     *
     * @author by M.Wang
     * @param int $int_id
     * @param int $int_page
     * @param int $int_limit
     * @param string $str_otherCondition
     * @return array
     */
    public function getOrdersByUserId( $int_id, $int_start, $int_limit, $str_otherCondition = '' ){
        return $this->orderDao->getOrdersByUserId( $int_id, $int_start, $int_limit, $str_otherCondition );
    }

    /**
     * get count(*)
     *
     * @param int $int_id
     * @param string $str_otherCondition
     * @return int
     */
    public function getOrdersCountRowsByUserId( $int_id, $str_otherCondition = null ){
        $arr_results = $this->orderDao->getOrdersByUserId( $int_id, null, null, $str_otherCondition, true );
        if( $arr_results ){
    	   $arr_results['Count'] = $this->dbUtil->getLastFoundRows();
    	 
    	}
        return $arr_results['Count'][0]['ROWS'];
    }

    /**
     * Get next step action setting
     *
     * @author by M.Wang
     * @param int $int_status
     * @param int $int_orderId
     * @return string
     */
    public function getOrderAction( $int_status, $int_orderId, $int_paymentId ){

        $arr_orderAction = array();

        /**
         * If the payment online option has been selected, then [Pay now] and [Cancel] need show on page. Else show [Cancel] only.
         */
        if( $int_paymentId > 2 && $int_paymentId < 10 ){
            $arr_orderAction[1] = array( "<span style='cursor:pointer;' onclick=\"window.open('/o/onlineorderpay?orderId=" . base64_encode($int_orderId) . "');openDialog();\">" . USERORDERACTIONPAY . '</span>', "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . USERORDERACTIONCANCELR . "')) orderActionNextStep({$int_orderId},6);\">" . USERORDERACTIONCANCEL . "</span>" );
        }else{
            $arr_orderAction[1] = array( "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . USERORDERACTIONCANCELR . "')) orderActionNextStep({$int_orderId},6);\">" . USERORDERACTIONCANCEL . "</span>" );
        }

        $arr_orderAction[2] = $arr_orderAction[1];
        $arr_orderAction[3] = array();
        $arr_orderAction[4] = array( "<span style='cursor:pointer;' onclick=\"window.open('https://www.alipay.com/trade/query_trade_list.htm?act=inner_query&page=0&page_size=10&_fmt.q._0.g=7&_fmt.q._0.tra=&_fmt.q._0.trade=&_fmt.q._0.o=B&_fmt.q._0.i=0');openDialog();\">" . USERORDERACTIONFINISH . '</span>' );
//        $arr_orderAction[4] = array( "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . USERORDERACTIONFINISHR . "')) orderActionNextStep({$int_orderId},5);\">" . USERORDERACTIONFINISH . '</span>', "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . USERORDERACTIONBACKR . "')) orderActionNextStep({$int_orderId},7);\">" . USERORDERACTIONBACK . '</span>' );
        $arr_orderAction[5] = array();
        $arr_orderAction[6] = array();
        $arr_orderAction[7] = array();

        $arr_orderAction[11] = array( "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . SCHOOLORDERACTIONENTERR . "')) orderActionNextStep({$int_orderId},12);\">" . SCHOOLORDERACTIONENTER . '</span>', "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . SCHOOLORDERACTIONCANCELR . "')) orderActionNextStep({$int_orderId},16);\">" . SCHOOLORDERACTIONCANCEL . '</span>' );
        $arr_orderAction[12] = array( "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . SCHOOLORDERACTIONBACKR . "')) orderActionNextStep({$int_orderId},17);\">" . SCHOOLORDERACTIONBACK . '</span>' );
        $arr_orderAction[13] = array( /*"<span onclick=\"if(window.confirm('" . SCHOOLORDERACTIONFINISHR . "')) orderActionNextStep({$int_orderId},15);\">" . SCHOOLORDERACTIONFINISH . '</span>',*/ "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . SCHOOLORDERACTIONBACKR . "')) orderActionNextStep({$int_orderId},17);\">" . SCHOOLORDERACTIONBACK . '</span>' );
        $arr_orderAction[14] = array( "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . SCHOOLORDERACTIONRECIVER . "')) orderActionNextStep({$int_orderId},13);\">" . SCHOOLORDERACTIONRECIVE . '</span>', "<span style='cursor:pointer;' onclick=\"if(window.confirm('" . SCHOOLORDERACTIONBACKR . "')) orderActionNextStep({$int_orderId},17);\">" . SCHOOLORDERACTIONBACK . '</span>' );
        $arr_orderAction[15] = array();
        $arr_orderAction[16] = array();
        $arr_orderAction[17] = array();

        if( empty( $arr_orderAction[ $int_status ] ) )
            return '';
        $str_result = '';
        foreach ( $arr_orderAction[$int_status] as $str_string )
            $str_result.= '/' . $str_string;
        return substr( $str_result, 1 );

    }

    /**
     * Update order.status
     *
     * @author by M.Wang
     * @param int $int_orderid
     * @param int $int_status
     * @return boolean
     */
    public function updateOrderStatus( $int_orderid, $int_status, $int_userid ){
        return $this->orderDao->updateOrderStatus( $int_orderid, $int_status, $int_userid );
    }

    /**
     * Format order_items data view.
     *
     * @author by M.Wang
     * @param array $arr_order
     * @param array $arr_items
     */
    public function getOrderItmesInfoTable( $arr_order, $arr_items ){
        ?>
            <table>
                <thead>
                    <tr>
                        <th><?php echo OLORDERITEMTH0 ?></th>
                        <th><?php echo OLORDERITEMTH1 ?></th>
                        <th><?php echo OLORDERITEMTH2 ?></th>
                        <th><?php echo OLORDERITEMTH3 ?></th>
                        <th><?php echo OLORDERITEMTH4 ?></th>
                   </tr>
                </thead>
                <tbody>
                    <?php foreach ( $arr_items as $arr_orderitem ): ?>
                        <tr>
                            <td><a href='/p/<?php echo $arr_orderitem['title'] ?>'><?php echo $arr_orderitem['title'] ?></a></td>
                            <td><?php echo MONEYTAG . $arr_orderitem['sale_price'] ?></td>
                            <td><?php echo $arr_orderitem['quantity'] ?></td>
                            <td><?php echo Order::getDefaultChequeRuleName( $arr_orderitem['cheque_rule'] ) . ( $arr_orderitem['tax'] ? '[' . MONEYTAG . $arr_orderitem['tax'] . ']' : '' ); ?></td>
                            <td><?php $int_total = $arr_orderitem['sale_price'] * $arr_orderitem['quantity'] + $arr_orderitem['tax']; echo MONEYTAG . number_format( $int_total, 2); ?></td>
                        </tr>
                    <?php endforeach; ?>
                </tbody>
                <tfoot>
                    <tr>
                        <td style='text-align:right;'><?php echo OLORDERITEMDISCOUNTTXT . $arr_order['discount_fee']; ?></td>
                        <td colspan='2' style='text-align:right;'><?php echo OLORDERITEMFREIGHTTXT . $arr_order['shipping_fee']; ?></td>
                        <td colspan='2' style='text-align:right;'><?php echo OLORDERITEMTOTALTXT . $arr_order['total']; ?></td>
                    </tr>
                </tfoot>
            </table>
        <?php
    }

    /**
     * Get package detail
     *
     * @author by M.Wang
     * @param int $int_orderid
     * @return array
     */
    public function getPackageInfoByOrderId( $int_orderid ){
        $arr_results = $this->orderPackageItemDao->getPackageItemsByOrderId( $int_orderid );
        if( !empty($arr_results ) ){
            foreach ($arr_results as $int_key => $arr_result){
                $arr_results[$int_key]['attributes'] = $this->getItemAttribute($arr_result['product_item_id']);
            }
        }
        return $arr_results;
    }

    ////////////////////////////////////////////////////////////////////////////////////////
       /**
        * freeze money
        */
       public function freezeMoney($userId,$tradeSum,$tradeType,$orderNum,$orderId,$tradeOperator){
            $logService = new SystemLogService();
            $agentTotals = $this->agentTotalDao->getAccountAgentTotalByUserId($userId);
            if(empty($agentTotals)){
                return false;
            }
            if($tradeType != 11 && $tradeType != 21 && $tradeType != 31){
                return false;
            }
            $agentTotal = $agentTotals[0];
            $usageTempBalance = $agentTotal['usage_balance'];
            $debtTempBalance = $agentTotal['debt_balance'];
            $debtTotalTemp = $agentTotal['debt_total'];
            if(($debtTotalTemp + $usageTempBalance - $debtTempBalance) < $tradeSum){
                return false;
            }
            $data = array();
            $data['user_id'] = $userId;
            $data['order_id'] = $orderId;
            $data['order_num'] = $orderNum;
            $data['trade_type'] = $tradeType;
            $data['trade_sum'] = $tradeSum;
            $data['trade_operator'] = $tradeOperator;
            $data['status'] = 1;
            $data['modified'] = date("Y-m-d H:i:s");
            $data['modify_id'] = $tradeOperator;
            $data['created'] = date("Y-m-d H:i:s");
            $data['create_id'] = $tradeOperator;
            //log表交易前账户的记录
            $data['balance_prev']=$agentTotal['balance'];
            $data['debt_prev']=$agentTotal['debt_balance'];
            $data['freeze_prev']=$agentTotal['freezed_balance'];
            $data['usage_balance_prev']=$agentTotal['usage_balance'];
            //total更新
            $agentData = array();
            $agentData['modified'] = date("Y-m-d H:i:s");
            $agentData['modify_id'] = $tradeOperator;

            $logtype="ADDAF";
            //log添加账户增减记录
            $data['account_freeze_offset']=$tradeSum;
            $data['account_usage_balance_offset']=-$tradeSum;
            //total账户改变
            $agentData['usage_balance']=$agentTotal['usage_balance']-$tradeSum;
            $agentData['freezed_balance']=$agentTotal['freezed_balance']+$tradeSum;
            $agentData['order_dealing_cnt']=$agentTotal['order_dealing_cnt']+1;
            $agentData['order_dealing_sum']=$agentTotal['order_dealing_sum']+$tradeSum;

            $data['balance_now']=$agentTotal['balance'];
            $data['debt_now']=$agentTotal['debt_balance'];
            $data['freeze_now']=$agentData['freezed_balance'];
            $data['usage_balance_now']=$agentData['usage_balance'];

            $logid=$this->accountAgentTradeLogDao->saveAccountAgentTradeLog($data);
            if(!empty($logid)){
                $this->UpdateTradLogSN($logid,$tradeType);
            }

            $logService->insertSystemLog($logtype,$tradeOperator,1,$data);
            $this->agentTotalDao->updateAccountAgentTotal($agentData,$agentTotal['id']);
            $logService->insertSystemLog($logtype,$tradeOperator,1,$agentData,$agentTotal['id']);
            return true;
       }

       private function UpdateTradLogSN($id,$tradeType){
            $data['sn'] = Number::getTradeLogSN($id,$tradeType);
            $this->accountAgentTradeLogDao->updateAccountAgentTradeLog($data,$id);
       }

     /**
      * return inventory by order id
      * @param $orderId
      */
       public function returnInventory($orderId){
            $items = $this->orderItemDao->getOrderInfoByOrderId($orderId);
            if(!empty($items)){
                 foreach($items as $item){
                     $itemId = $item['item_id'];
                     $quantity = $item['quantity'];
                     $this->productItemDao->returnInventoryByItemId($itemId,$quantity);
                 }
            }
            return true;
       }

       public function setOrderReturned($orderId, $int_returnedSet){
           return $this->orderDao->updateOrderReturned($orderId,$int_returnedSet);
       }

    /**
     * 获取订单的下一步状态，包含了当前用户对于该订单的操作权限检查
     *
     * @param array $arr_order
     * @param int $int_userid
     * @return int
     */
    public function getOrdersNextStatus($arr_order, $int_userid, $int_status = null){
        if(!empty($arr_order['agent_id'])){
            if( $arr_order['agent_id']!=$int_userid )
                return false;
        }else{
            if( $arr_order['user_id']!=$int_userid )
                return false;
        }

        if( !empty($int_status) ){
            $int_mStatus = $int_status%10;
            if($int_mStatus==7||$int_mStatus==6)
                return $int_status;
        }
        switch($arr_order['status']){
            case 1://非校园订单已提交
            case 2://非校园订单已修改
                return 3;//已付款
            case 11://校园订单已提交
                return 12;//校园订单已确认
            case 14://卖家已发货
                return 13;//校园代理已收货
            //退货申请时不修改当前状态
            case 6:
            case 7:
            case 16:
            case 17:
                return $int_status;
            default:
                return false;
        }
    }

    public function getOrderByOrderNo($orderNo){
    	$results = $this->orderDao->getOrderByOrderNo($orderNo);
    	if(!empty($results)){
    		return $results[0];
    	}
    	return "";
    }

    public function updateOrderById($order,$id){
        $this->orderDao->updateOrderById($order,$id);
    }

    public function updateUserPoint($total,$userId,$orderNumber){
        $users = $this->userDao->getUserById($userId);
        if(!empty($users)){
        	$user = $users[0];
        	$certf = $user['certf'];
        	if($certf == 1 || $certf == 6){
        		 $desc = "订单".$orderNumber."交易成功获得积分";
        		 $userPointService = new UserPointService();
        		 $userPointService->updatePoint($userId,round($total),4,$desc);
        	}
        }
        
        
    }


}